package com.m4f.city.web.controller.admin;

import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.cache.CacheException;
import javax.validation.Valid;

import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.m4f.city.business.domain.Company;
import com.m4f.city.business.security.InternalUserDetailService;
import com.m4f.city.utils.table.DataTable2;
import com.m4f.city.web.controller.BaseController;
import com.m4f.city.web.form.CompanyForm;
import com.m4f.gaeweb.web.utils.StackTraceUtil;

@Controller
@Secured(InternalUserDetailService.ROLE_ROOT)
@RequestMapping("/admin/company")
public class CompanyAdminController extends BaseController {
	private static final Logger LOGGER = Logger.getLogger(CompanyAdminController.class.getName());
	
	public CompanyAdminController() throws CacheException {
		super();
	}
	
	@RequestMapping(method=RequestMethod.GET)
	public String getForm(Model model, Locale locale) {
		try {
			Company company = this.serviceLocator.getCompanyService().create();
			model.addAttribute("form", new CompanyForm(company));
		} catch(Exception e) {
			LOGGER.severe(StackTraceUtil.getStackTrace(e));
			return "common.error";
		}
		return "admin.company.edit";
	}
	
	@RequestMapping(method=RequestMethod.POST)
	public String save(@ModelAttribute("form") @Valid CompanyForm form, 
			BindingResult result, Model model, Locale locale) {
		boolean updateAction = false;
		try {
			if(result.hasErrors()) {
				return "admin.company.edit";
			}
			
			Company company = form.getCompany();
			if(company.getId() != null) updateAction = true;
			this.serviceLocator.getCompanyService().save(company);
			if(updateAction) addSuccessMessage("message.success.admin.company.updated");
			else addSuccessMessage("message.success.admin.company.created");
		} catch(Exception e) {
			if(updateAction) addErrorMessage("message.error.admin.company.updated");
			else addErrorMessage("message.error.admin.company.created");
			LOGGER.severe(StackTraceUtil.getStackTrace(e));
			return "common.error";
		}
		
		return getRedirect("/admin/company/list", locale);
	}
	
	@RequestMapping(value="/list", method=RequestMethod.GET)
	public String list() {
		return "admin.company.list";
	}
	
	@RequestMapping(value="/edit/{companyId}", method=RequestMethod.GET)
	public String edit(@PathVariable Long companyId, Model model, Locale locale) {
		try {
			Company company = this.serviceLocator.getCompanyService().getObjectById(companyId);
			
			model.addAttribute("form", new CompanyForm(company));
		} catch(Exception e) {
			LOGGER.severe(StackTraceUtil.getStackTrace(e));
			return "common.error";
		}
		return "admin.company.edit";
	}
	
	@RequestMapping(value="/delete/{companyId}", method=RequestMethod.GET)
	public String delete(@PathVariable Long companyId, Locale locale) {
		try {
			Company company = this.serviceLocator.getCompanyService().getObjectById(companyId);
			this.serviceLocator.getCompanyService().delete(company);
			addSuccessMessage("message.success.admin.company.deleted");
		} catch(Exception e) {
			addErrorMessage("message.error.admin.company.deleted");
			LOGGER.severe(StackTraceUtil.getStackTrace(e));
			return "common.error";
		}
		
		return getRedirect("/admin/company/list", locale);
	}
	
	@RequestMapping(value="/detail/{companyId}", method=RequestMethod.GET)
	public String detail(@PathVariable Long companyId, Model model, Locale locale) {
		try {
			Company company = this.serviceLocator.getCompanyService().getObjectById(companyId);
			model.addAttribute("company", company);
		} catch(Exception e) {
			LOGGER.severe(StackTraceUtil.getStackTrace(e));
			return "common.error";
		}
		return "admin.company.detail";
	}

	// TABLE
	@RequestMapping(value="/list/table")
	@ResponseBody
	public DataTable2<Company> table3(@RequestParam(required=false) Integer iDisplayStart, @RequestParam(required=false) Integer iDisplayLength, /* Pagination */
			@RequestParam(required=false) Integer iSortCol_0, @RequestParam(required=false) String sSortDir_0, /* Sorting */
			@RequestParam(required=false, defaultValue="") String sSearch /* Search */) {
		try {
			
			// Filter 
			// TODO Now its difficult to filter by columns. So there is a general filter and here we have to set the default column to filter.
			String filterBy = "name";
			String filterValue = sSearch;
			// End filter
			
			DataTable2<Company> table = iDisplayLength != null ?
					new DataTable2<Company>(new String[]{"id", "name"}, sSortDir_0, iDisplayStart, iDisplayLength) :
					new DataTable2<Company>(new String[]{"id", "name"}, sSortDir_0, iDisplayStart);
			table.setRows(this.serviceLocator.getCompanyService().getObjectsBy(table.getOrdering(iSortCol_0), filterBy, filterValue, table.getStart(), table.getEnd()));
			table.setiTotalDisplayRecords(this.serviceLocator.getCompanyService().count()); // TODO 
			return table;
		} catch(Exception e) {
			LOGGER.log(Level.SEVERE, StackTraceUtil.getStackTrace(e));
			return new DataTable2<Company>();
		}
	}	
}